package test.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ParameterizedTypeBean {
    // 下面的 field 的 Type 属于 ParameterizedType
    Map<String, Object> map;
    Set<String> set1;
    Class<?> clz;
    Holder<String> holder;
    List<String> list;
    // Map<String,Person> map 这个 ParameterizedType 的 getOwnerType() 为 null，
    // 而 Map.Entry<String, String> entry 的 getOwnerType() 为 Map 所属于的 Type。
    Map.Entry<String, String> entry;
    // 下面的 field 的 Type 不属于ParameterizedType
    String str;
    Integer i;
    Set set;
    List aList;

    static class Holder<V> {

    }
}

class TestHelper {

    public static void main(String[] args) {
        Field f = null;
        try {
            Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();
            // 打印出所有的 Field 的 TYpe 是否属于 ParameterizedType
            for (int i = 0; i < fields.length; i++) {
                f = fields[i];
                PrintUtils.print(f.getName()
                        + " getGenericType() instanceof ParameterizedType "
                        + (f.getGenericType() instanceof ParameterizedType));
            }
            getParameterizedTypeMes("map");
            getParameterizedTypeMes("entry");
            getParameterizedTypeMes("holder");


        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private static void getParameterizedTypeMes(String fieldName) throws NoSuchFieldException {
        Field f;
        f = ParameterizedTypeBean.class.getDeclaredField(fieldName);
        f.setAccessible(true);
        PrintUtils.print(f.getGenericType());
        boolean b = f.getGenericType() instanceof ParameterizedType;
        PrintUtils.print(b);
        if (b) {
            ParameterizedType pType = (ParameterizedType) f.getGenericType();
            PrintUtils.print(pType.getRawType());
            for (Type type : pType.getActualTypeArguments()) {
                PrintUtils.print(type);
            }
            PrintUtils.print(pType.getOwnerType()); // null
        }
    }
}

class PrintUtils {
    static void print(Object o) {
        System.out.println(o);
    }
}